//
//  UIApplication+FPlugin.h
//  FFoundation
//
//  Created by 三井 on 2019/11/7.
//

#import <UIKit/UIKit.h>
#import "NSObject+FPlugin.h"
#import "FPlugin.h"

NS_ASSUME_NONNULL_BEGIN

@class FPluginCallCommend;
@protocol FPluginCallable <FPlugin>

@optional

/// 被请求服务
/// @param cmd 服务命令
- (id)pluginCall:(FPluginCallCommend *)cmd;

/// 声明实现的协议，方面直接调用
- (NSArray<Protocol *> *)pluginBind;

@end

@interface UIApplication (FPlugin)

@end

#pragma mark - Call Commend
@class FPluginCallCommend;
typedef NSString * FPluginCallCommendParamKey;
typedef void (^FPluginCallCommendCallback)(FPluginCallCommend *cmd);
@interface FPluginCallCommend : NSObject

@property (nonatomic, copy) NSString *srcid;    ///< srouce id
@property (nonatomic, copy) NSString *tarid;    ///< target id
@property (nonatomic, copy) NSString *method;   ///< method
@property (nonatomic, copy) NSDictionary<FPluginCallCommendParamKey, id> *params;

// call back and result
@property (nonatomic, copy) FPluginCallCommendCallback callback;
@property (nonatomic, strong) id result;

+ (instancetype)callCommend:(void (NS_NOESCAPE ^)(FPluginCallCommend * cmd))build;

@end

NS_ASSUME_NONNULL_END

/// 插件之间的相互调用
/// @param selfid 调用者的id
/// @param method 方法名
/// @param params 参数
/// @param callback 回调，如果需要的话
FOUNDATION_EXPORT id _Nullable PluginCall(NSString * _Nullable selfid, NSString * _Nullable target, NSString * _Nonnull method, NSDictionary * _Nullable params, FPluginCallCommendCallback _Nullable callback);
FOUNDATION_EXPORT id _Nullable PluginCommendCall(FPluginCallCommend * _Nonnull commend);

/// 获取对应协议的实现实例
/// @param ptl 协议
FOUNDATION_EXPORT id _Nullable PluginProtocol(Protocol * _Nonnull ptl);
#define _PP(_p_) ((id<_p_>)PluginProtocol(@protocol(_p_)))

#define kPluginCallBegin( _cmd_ ) __unused FPluginCallCommend *_plugin_call_cmd_ = _cmd_;if (0) {
#define kPluginCall( _method_ ) } else if ([_plugin_call_cmd_.method isEqualToString:_method_]) {
#define kPluginCallEnd }else{}
